/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root1
 * @param {TreeNode} root2
 * @return {number[]}
 */
 var getAllElements = function(root1, root2) {
  const traverse = function* (node){
    if(node.left) {
      yield *traverse(node.left);
    }
    yield node.val;
    if(node.right) {
      yield *traverse(node.right);
    }
    return;
  }
  let g1 = root1 && traverse(root1);
  let g2 = root2 && traverse(root2);
  let v1 = root1 ? g1.next() : {done: true};
  let v2 = root2 ? g2.next() : {done: true};
  let curr = root1 && root2 ? Math.max(v1.value, v2.value) : undefined;
  const ret = [];
  while(!v1.done || !v2.done) {
    while(!v1.done && (curr === undefined || v1.value < curr )) {
      ret.push(v1.value);
      v1 = g1.next();
    }
    curr = v1.value;
    while(!v2.done && (curr === undefined || v2.value < curr)) {
      ret.push(v2.value);
      v2 = g2.next();
    }
    while(!v1.done && v1.value === curr) {
        ret.push(v1.value);
        v1 = g1.next();
    }
    while(!v2.done && v2.value === curr) {
        ret.push(v2.value);
        v2 = g2.next()
    }
    curr = v1.done || v2.done ? undefined : Math.max(v1.value, v2.value);
  }
  return ret;
};